from pymodbus.client import ModbusTcpClient
import time


def convert_registers_to_string(registers):
    """将寄存器值转换回字符串"""
    result = ""
    for register in registers:
        # 从寄存器中提取高字节和低字节
        high_byte = (register >> 8) & 0xFF
        low_byte = register & 0xFF
        # 将字节转换为字符
        result += chr(high_byte) + chr(low_byte)
    return result


def read_modbus_data(client, address=0, count=50):
    """读取Modbus寄存器数据"""
    try:
        # 读取保持寄存器
        result = client.read_holding_registers(address, count)
        if result.isError():
            print(f"读取错误: {result}")
            return None

        # 将寄存器值转换为字符串
        message = convert_registers_to_string(result.registers)
        return message.strip()
    except Exception as e:
        print(f"发生错误: {e}")
        return None


def main():
    # Modbus TCP服务器地址和端口
    server_ip = "192.168.1.110"  # 修改为发送端的IP地址
    server_port = 1502

    print(f"正在连接到 Modbus TCP 服务器 {server_ip}:{server_port}")

    while True:
        try:
            # 创建Modbus TCP客户端
            client = ModbusTcpClient(
                host=server_ip,
                port=server_port,
                timeout=30,  # 增加超时时间
                retry_on_empty=True,  # 空响应时重试
                retry_on_invalid=True,  # 无效响应时重试
                retries=3  # 重试次数
            )

            if client.connect():
                print("成功连接到服务器")
                print("开始接收数据...")

                # 持续读取数据
                while True:
                    try:
                        data = read_modbus_data(client)
                        if data:
                            print(f"收到数据: {data}")
                        time.sleep(1)  # 每秒读取一次
                    except Exception as e:
                        print(f"读取数据时发生错误: {e}")
                        break  # 发生错误时跳出内层循环

            else:
                print("连接服务器失败，5秒后重试...")
                time.sleep(5)

        except KeyboardInterrupt:
            print("\n程序已停止")
            break
        except Exception as e:
            print(f"发生错误: {e}")
            print("5秒后重试连接...")
            time.sleep(5)
        finally:
            try:
                client.close()
            except:
                pass


if __name__ == "__main__":
    main()

